Немного о том, как я написал парсер языка О. Хотя NETCH80 и ругает у себя в
посте язык К справедливо, хочу попытаться зафиксировать основные правила
синтаксиса и привнести некоторый порядок в язык, предоставив формальную нотацию
для LR парсеров. Имплементация прототипа делалась на lalrpop — это нетабличный
однопроходной LR парсер который поставляется с голимым регэксп токенайзером.
Токенайзер вместо регекспов хочется кастомный на NOM, но руки не доходят.
Существует три вида скобочек: [], (), {} — множества, списки и лямбды. Другими
словами это M-expressions, S-expressions и Лямбда-калкулус соответственно
(который в К можно представить как Pi-calculus, так как K-Cell содержит вектор,
а значит все параметры — это стримы, и если трактовать срабатывание функции на
появление нового элемента в любом стриме-параметре, то это уже будет
Пи-калкулус и CHR, штука которая полезна не только для моделирования
самобалансирующего скедулера но для потокового бизнес роутинга).
Эти Nil могут либо схлопываться, либо рости при встраиваниях. Например [[]] и
(()) не изменяются при встраиваниях, а {{}} растет:
Изменяя способ расстановки скобочек можно догадаться какие основные правила
создания выражений:
Nil можно вызывать друг у друга в цепочке, отлично. Более общее правило:
аппликация через пробел в любом ближайшем скобочном контексте всегда одинакова:
Если множество в своем списке-носителе содержит присваивания к именам то такой
множество трактуется как словарь, если список множества — это просто имена — то
это бинд параметр функции {[x;y;z]...}, если параметр множества если функция
без параметров бинда, то x,y,z трактуются как имена контекста по умолчанию.
Если члены списка словаря просто выражения, то это множество носитель
параметров. Множества называются M-expressions.
Списки тоже можно конкатенейтить через Semicolon, вообще у Semicolon
максимальный приоритет и она разделяет все экспрешины. Это в сущности одни и те
же списки, только данные обрамленные конструкторами, а колл-чейн более
абстрактный, и он тоже конвертируется с список но в общем случае может состоять
из любых K-Cell.
У меня получилась BNF нотация на 13 правил. Что скажете? Можно короче, красивее?
Терминалы думаю написать на NOM попробовать, чтобы быстрее парсалось.
Этот парсер парсает все исходники К и Q которые мне попадались на глаза,
включая диалекты типа Kona (K4) и oK.js (K5). Это около 128КБ, включая саму
имплементацию Q, каталоги примеров других диалектов и корпоративный
продакшиновский К код. Принципиальной и абсолютной совестимости я не хочу, но
максимальное покрытие диалектов и высокая портируемость не помешает.